package com.twt.config.mybatis;

import com.twt.config.mybatis.surppot.DataSourceBuildFactory;
import com.twt.config.mybatis.surppot.DataSourceBuilder;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
import org.springframework.boot.context.properties.bind.BindResult;
import org.springframework.boot.context.properties.bind.Bindable;
import org.springframework.boot.context.properties.bind.Binder;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Arrays;

/**
 * @Desciption:
 * @ClassName:MybatisRegistry
 * @Author:TwT
 * @Date:2022/6/3 13:16
 * @Version:1.0
 **/
@Component
public class MybatisRegistry implements BeanDefinitionRegistryPostProcessor, EnvironmentAware {
    private Environment environment;
    private Binder binder;

    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
        String dataSources = this.environment.getProperty("twt.datasource.data-source-list");
        Arrays.asList(dataSources.replaceAll("，", ",").split(",")).stream().forEach(beanName -> {
            BindResult<MybatisDataSourceProperty> bindResult = this.binder.bind("twt.datasource." + beanName, Bindable.of(MybatisDataSourceProperty.class));
            MybatisDataSourceProperty mybatisDataSourceProperty = bindResult.get();
            this.registryBean(beanDefinitionRegistry, mybatisDataSourceProperty, beanName);
        });
    }

    private void registryBean(BeanDefinitionRegistry registry, MybatisDataSourceProperty dataSourceProperty, String beanName) {
        String datasourceType = dataSourceProperty.getDatasourceType();

        DataSourceBuildFactory dataSourceBuildFactory = new DataSourceBuildFactory();
        DataSourceBuilder dataSourceBuilder = dataSourceBuildFactory.getDataSourceBuilder(datasourceType);
        dataSourceBuilder.setBeanDefinitionRegistry(registry);
        dataSourceBuilder.setBeanName(beanName);
        dataSourceBuilder.setMybatisDataSourceProperty(dataSourceProperty);

        dataSourceBuilder.registry();
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {

    }

    @Override
    public void setEnvironment(Environment environment) {
        this.environment = environment;
        this.binder = Binder.get(environment);
    }
}
